import uuid
import json
import re

from flask import Response, jsonify, Flask, request, Blueprint, url_for
from configs import *
from datetime import datetime, timedelta
# 创建蓝图，对应的register目录（激活操作视图）
activate = Blueprint('activate', __name__)


# 产品信息获取生成ak文件
@activate.route('/product_information', methods=['POST'])
def product_information():
    # 用户名称
    username = strip_whitespace(request.form.get('username', None))
    # 公司
    company = strip_whitespace(request.form.get('company', None))
    # 国家
    nation = strip_whitespace(request.form.get('nation', None))
    # 电话
    mobile = strip_whitespace(request.form.get('mobile', None))
    # 省
    province = strip_whitespace(request.form.get('province', None))
    # 市
    city = strip_whitespace(request.form.get('city', None))
    # 地址
    address = strip_whitespace(request.form.get('address', None))
    # 激活时间
    time = strip_whitespace(request.form.get('time', None))

    # 获取机器的UUID
    machine_uuid = uuid.UUID(int=uuid.getnode())
    # print(f"Machine UUID: {machine_uuid}")

    # 添加有效期（例如，有效期30天）
    valid_until = strip_whitespace(request.form.get('valid_until', None))
    # valid_until = (datetime.now() + timedelta(days=30)).strftime('%Y-%m-%d %H:%M:%S')

    # 激活标识key
    key = activate_key

    # 参数构建判断是否为空
    params = [username, company, nation, mobile, province, city, address, time]

    if not all(params):
        return jsonify({'code': 400, 'msg': '设备数据有未填写项'})

    # 收集所有信息到一个字典
    info = {
        'username': username,
        'company': company,
        'nation': nation,
        'mobile': mobile,
        'province': province,
        'city': city,
        'address': address,
        'time': time,
        'machine_uuid': str(machine_uuid),
        'key': key,
        'date_time': str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
        'activate_valid_until' : valid_until
    }

    # 将信息转换为JSON字符串
    info_string = json.dumps(info, sort_keys=True)
    key = cipher_suite.encrypt(info_string.encode())

    info_block = """--------------------------------------------------------- BEGIN Information ---------------------------------------------------------
    Software description     : 平台激活序列
    Extended description     : 序列生成
    Type                     : 激活码
--------------------------------------------------------- END Information ---------------------------------------------------------"""

    activation_block = f"""--------------------------------------------------------- BEGIN BLOCK ---------------------------------------------------------
{key.decode()}
--------------------------------------------------------- END BLOCK ---------------------------------------------------------"""

    activation_block_key = f"""--------------------------------------------------------- BEGIN BLOCK KEY ---------------------------------------------------------
{key_key.decode()}
--------------------------------------------------------- END BLOCK KEY ---------------------------------------------------------"""

    # 完整的激活文件内容
    ak_file_content = f"""---------------------------------------------------------- Activation File ---------------------------------------------------------
    #PLEASE DO NOT MODIFY THIS FILE. MAKING ANY CHANGE TO THIS FILE WILL INVALIDATE YOUR LICENSE.
    Copyright (C) 2024 Your Company Name. All rights reserved.

{info_block}

{activation_block}

{activation_block_key}
"""
    # 在 static 目录下新建 ak_create 目录
    ak_create_path = os.path.join(FILE_SAVE_PATH, 'ak_create')
    os.makedirs(ak_create_path, exist_ok=True)  # 如果目录不存在则创建

    # ak文件
    ak_name = 'activation_file_{}.ak'.format(datetime.now().strftime('%Y%m%d%H%M%S'))

    # 拼接完整的文件保存路径
    file_path = os.path.join(ak_create_path, ak_name)

    # 确保目录存在
    os.makedirs(ak_create_path, exist_ok=True)

    # 写入文件
    with open(file_path, "w") as file:
        file.write(ak_file_content)

    return jsonify(
        {'code': 200, 'msg': 'ak激活码文件生成', 'file': 'http://{}:5000/static/ak_create/{}'.format(DB_HOST, ak_name)})


# ak激活文件上传及验证
@activate.route('/product_upload', methods=['POST'])
def product_upload():
    def extract_activation_key(file_path):
        def clean_text(text):
            # 使用正则表达式去除上下的两条线和换行符
            cleaned_text = re.sub(r'^\s*-+\s*|\s*-+\s*$', '', text, flags=re.MULTILINE)
            return cleaned_text.strip()

        with open(file_path, 'r') as file:
            content = file.read()
        # 使用正则表达式提取 BEGIN BLOCK 和 END BLOCK 之间的内容
        match = re.search(
            r'BEGIN BLOCK\s*(.*?)\s* END BLOCK',
            content, re.DOTALL)
        match_key = re.search(
            r'BEGIN BLOCK KEY\s*(.*?)\s* END BLOCK KEY',
            content, re.DOTALL)
        if match:
            activation_key = match.group(1).strip()
            activation_key_key = match_key.group(1).strip()
            return clean_text(activation_key), clean_text(activation_key_key)
        else:
            return "文件中没有找到激活码！"

    # 解析ak文件内容
    files = request.files.get('files', None)

    # 判断当文件存在时
    if files:

        # 在 static 目录下新建 ak_activate 目录
        ak_activate_path = os.path.join(FILE_SAVE_PATH, 'ak_activate')
        os.makedirs(ak_activate_path, exist_ok=True)  # 如果目录不存在则创建

        # 文件名
        filename = files.filename
        # 拼接文件保存路径
        file_path = os.path.join(ak_activate_path, filename)

        # 将文件保存到 ak_activate 目录下
        files.save(file_path)

        try:
            # 提取密钥和加密数据
            res = extract_activation_key(file_path)

            # 进行编码处理
            key = res[1].encode()  # 从请求中获取密钥
            encrypted_data = res[0].encode()  # 从请求中获取加密数据
            print(encrypted_data)

            # 解密
            cipher_suite = Fernet(key)
            decrypted_info = cipher_suite.decrypt(encrypted_data).decode()

            # 将解密后的 JSON 字符串转换为字典
            info_dict = json.loads(decrypted_info)
            print(info_dict)

            # 对秘钥进行比对，如果比对成功，数据写入，并且系统数据状态发生改变
            if info_dict.get('key') != activate_key:
                return jsonify({'code': 400, 'msg': 'ak导入校验错误,请导入正确ak激活序列文件!'})

            # 判断key跟激活码是否存在，如果存在代表该激活码已经实用，请重新获取激活码
            res = db.session.query(Activate_info).filter(Activate_info.activate_key == key,
                                                         Activate_info.activate_encrypted_data == encrypted_data,
                                                         Activate_info.activate_status == 0,
                                                         ).first()
            if res:
                return jsonify({'code': 400, 'msg': '该激活码已经使用，请重新获取激活码!'})

            activate_data = Activate_info(
                activate_username=info_dict.get('username'),
                activate_company=info_dict.get('company'),
                activate_nation=info_dict.get('nation'),
                activate_mobile=info_dict.get('mobile'),
                activate_province=info_dict.get('province'),
                activate_city=info_dict.get('city'),
                activate_address=info_dict.get('address'),
                activate_time=info_dict.get('time'),
                activate_key=key,
                activate_encrypted_data=encrypted_data,
                activate_status='1',
                activate_valid_until=info_dict.get('activate_valid_until'),
            )
            db.session.add(activate_data)
            db.session.commit()

            # 装饰器，监听激活码数据时间，如果该时间到期，状态更改，如果为永久则不昨改动

        except FileNotFoundError:
            return jsonify({'code': 400, 'msg': 'ak导入校验错误,请导入正确ak激活序列文件!'})
        except InvalidToken:
            return jsonify({'code': 400, 'msg': 'ak导入校验错误,请导入正确ak激活序列文件!'})
        except json.JSONDecodeError:
            return jsonify({'code': 400, 'msg': 'ak导入校验错误,请导入正确ak激活序列文件!'})
        except Exception as e:
            return jsonify({'code': 400, 'msg': 'ak导入校验错误,请导入正确ak激活序列文件!'})

        return jsonify({'code': 200, 'msg': 'ak激活码文件生成', })
    else:
        return jsonify({'code': 400, 'msg': 'ak文件未上传!', })


# 平台激活序列判断
@activate.route('/activate_verify', methods=['GET'])
def activate_verify():
    # 获取激活码序列数据及对应状态确认系统
    res = db.session.query(Activate_info).all()
    # 标记是否有有效的激活记录
    valid_activation_found = False
    if not res:
        return jsonify({"msg": "该系统尚未激活！请登录运管中心授权！", 'code': 400})
    else:
        for i in res:
            current_time = datetime.now()
            valid_until = datetime.strptime(i.activate_valid_until, '%Y-%m-%d')
            if valid_until:
                if current_time > valid_until:
                    i.activate_status = 0
                else:
                    valid_activation_found = True
        db.session.commit()

        if valid_activation_found:
            return jsonify({"msg": "系统已激活！", 'code': 200})
        else:
            return jsonify({"msg": "系统激活序列已过期！！", 'code': 400})


# 激活序列内容编码展示
@activate.route('/activate_show', methods=['GET'])
def activate_show():
    res = db.session.query(Activate_info).all()
    res = convert_folder_to_dict_list(res, ['id', 'activate_username', 'activate_company', 'activate_nation',
                                            'activate_mobile',
                                            'activate_province', 'activate_city', 'activate_address', 'activate_time',
                                            'activate_key',
                                            'activate_encrypted_data', 'activate_status', 'created_at', 'updated_at','activate_valid_until'])
    return jsonify({"msg": "查询成功", 'data': res})